GICv2: Fix populating PE target data
authorJeenu Viswambharan <[email protected]>
Tue, 7 Nov 2017 16:10:19 +0000 (16:10 +0000)
committerJeenu Viswambharan <[email protected]>
Mon, 13 Nov 2017 07:49:30 +0000 (07:49 +0000)
This patch brings in the following fixes:

  - The per-PE target data initialized during power up needs to be
    flushed so as to be visible to other PEs.

  - Setup per-PE target data for the primary PE as well. At present,
    this was only setup for secondary PEs when they were powered on.

Change-Id: Ibe3a57c14864e37b2326dd7ab321a5c7bf80e8af
Signed-off-by: Jeenu Viswambharan <[email protected]>
drivers/arm/gic/v2/gicv2_main.c
plat/arm/common/arm_gicv2.c

index 25296a63e4e66501b70837b395e1846ce897ace3..4b0984d8a9c020de52ab93fabf476b06f8b463bc 100644 (file)
@@ -308,9 +308,26 @@ void gicv2_set_pe_target_mask(unsigned int proc_num)
        if (driver_data->target_masks[proc_num])
                return;
 
-       /* Read target register corresponding to this CPU */
-       driver_data->target_masks[proc_num] =
-               gicv2_get_cpuif_id(driver_data->gicd_base);
+       /*
+        * Update target register corresponding to this CPU and flush for it to
+        * be visible to other CPUs.
+        */
+       if (driver_data->target_masks[proc_num] == 0) {
+               driver_data->target_masks[proc_num] =
+                       gicv2_get_cpuif_id(driver_data->gicd_base);
+#if !HW_ASSISTED_COHERENCY
+               /*
+                * PEs only update their own masks. Primary updates it with
+                * caches on. But because secondaries does it with caches off,
+                * all updates go to memory directly, and there's no danger of
+                * secondaries overwriting each others' mask, despite
+                * target_masks[] not being cache line aligned.
+                */
+               flush_dcache_range((uintptr_t)
+                               &driver_data->target_masks[proc_num],
+                               sizeof(driver_data->target_masks[proc_num]));
+#endif
+       }
 }
 
 /*******************************************************************************
index b081fa8d98ee320f24a2b1ae531c2d8272031ddd..5644c60404134191c228d3f5e455bd7ef0fcabbf 100644 (file)
@@ -51,6 +51,7 @@ void plat_arm_gic_init(void)
 {
        gicv2_distif_init();
        gicv2_pcpu_distif_init();
+       gicv2_set_pe_target_mask(plat_my_core_pos());
        gicv2_cpuif_enable();
 }